package org.jdcenter.jndi.context;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;

public abstract class ProxyContext extends ContextAdapter {
	
	protected Context delegateContext = null;
	
	protected StubContext stubContext = null;
	
	protected final static String rootNamespace = "JDStream";
	protected final static String rootNamespace2 = "/JDStream";
	protected final static String separator = "/";
	
	 protected void init() throws NamingException{
	    	
	    	try {
	    		Class clazz = Class.forName(getStubContextName());
				stubContext = (StubContext)clazz.newInstance();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			stubContext.setProxyContext(this);
			stubContext.start();
	}
	protected abstract String getStubContextName();
	protected String checkName(String name) throws NamingException{
		String name_ = name;
    	if(name_.startsWith(rootNamespace+separator)){
    		return name_;
    	}
    	if(name_.startsWith(rootNamespace2+separator)){
    		String name2 = name_.substring(1);
    		return name2;
    	}
    	throw new NamingException("name must start with "+rootNamespace+separator);
    }
	
	protected Name checkName(Name name) throws NamingException{
    	if(rootNamespace.equals(name.get(0))){
    		if(name.size() > 1){
    			return name;
    		}
    		throw new NamingException("size of name must be above 2");
    	}
    	throw new NamingException("name must be "+rootNamespace+separator +" at first posn");
    }
	
	public static String getRootNamespace(){
		return rootNamespace;
	}
	
	public Object lookup(String name) throws NamingException {    	
    	return delegateContext.lookup(checkName(name));
    }
    
    public Object lookup(Name name) throws NamingException {
    	return delegateContext.lookup(checkName(name));
    }
    public void bind(String name, Object obj) throws NamingException {
    	delegateContext.bind(checkName(name), obj);
    }

    public void rebind(String name, Object obj) throws NamingException {
    	delegateContext.rebind(checkName(name), obj);
    }

    public void unbind(String name) throws NamingException {
    	delegateContext.unbind(checkName(name));
    }
    
    public void bind(Name name, Object obj) throws NamingException {
    	delegateContext.bind(checkName(name), obj);
    }
    
    public void rebind(Name name, Object obj) throws NamingException {
    	delegateContext.rebind(checkName(name), obj);
    }
    
    public void unbind(Name name) throws NamingException {
    	delegateContext.unbind(checkName(name));
    }

}
